package com.istock.user.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.istock.base.common.api.model.ApiBaseResponse;
import com.istock.base.common.api.model.PageInfo;
import com.istock.base.common.api.model.RetStatusEnum;
import com.istock.base.serializer.JsonSerializer;
import com.istock.base.serializer.json.JsonSerializerFactory;
import com.istock.union.user.client.SSOClientUtils;
import com.istock.union.user.model.Constants;
import com.istock.union.user.model.DeptInfo;
import com.istock.union.user.model.OperLog;
import com.istock.union.user.model.SSOUser;
import com.istock.union.user.model.SecurityChecker;
import com.istock.union.user.model.TenantInfo;
import com.istock.union.user.service.DeptInfoService;
import com.istock.union.user.service.TenantInfoService;

@RequestMapping("/s/deptInfo")
@Controller
public class DeptInfoController {

	private static final Logger logger = LoggerFactory.getLogger(DeptInfoController.class);
	
	@Autowired
	private DeptInfoService deptService;
	
	@Autowired
	private TenantInfoService tenantService;

	@SecurityChecker("user:deptInfo:search")
	@RequestMapping("/showList")
	public String showList(ModelMap model) {
		model.put("isAdmin" , SSOClientUtils.getInstance().isAdmin());
		return "user-app/deptInfo/list";
	}

	@SecurityChecker("user:deptInfo:search")
	@RequestMapping("/search")
	@ResponseBody
	public List<DeptInfo> search(DeptInfo deptInfo) {
		SSOUser user = SSOClientUtils.getInstance().findCurrentUser();
		return deptService.queryDeptTree(user.getTenantNo(), user.getCurrentDept() != null ?user.getCurrentDept().getDeptCode():null
				, deptInfo.getDeptName(), deptInfo.getDeptCode());
	}

	/**
	 * 新增
	 */
	@RequestMapping("/addPre")
	public String add(ModelMap model) {
		// 如果超级管理员时需要给出可选租户
		if (SSOClientUtils.getInstance().isAdmin()) {
			TenantInfo tenantQuery = new TenantInfo();
			tenantQuery.setStatus(Constants.COMMON_VALID);
			model.put("tenantList", tenantService.findTanantList(tenantQuery , new PageInfo(1000)));
		}
		
		//给定页面能够选择的组织机构树
		SSOUser user = SSOClientUtils.getInstance().findCurrentUser();
		List<Map<String , Object>> deptList = deptService.queryDeptTreeData(user.getTenantNo(), user.getCurrentDept() != null ?user.getCurrentDept().getDeptCode():null 
				, SSOClientUtils.getInstance().isAdmin(),true);
		JsonSerializer serializer = JsonSerializerFactory.findSerializer();
		model.put("treeData", serializer.serialize(deptList));
//		model.put("treeData", JSON.toJSONString(deptList));
		
		model.put("isAdmin" , SSOClientUtils.getInstance().isAdmin());
		
		return "user-app/deptInfo/add";
	}

	/**
	 * 新增保存组织机构
	 */
	@SecurityChecker("user:deptInfo:add")
	@RequestMapping("/add")
	@ResponseBody
	@OperLog(functionName="新增",menuName="组织机构管理")
	public ApiBaseResponse<Boolean> addSave(DeptInfo deptInfo) {
		try {
			deptInfo.setCreateBy(SSOClientUtils.getInstance().findCurrentUser().getLoginName());
			if (StringUtils.isBlank(deptInfo.getParentId()) && StringUtils.isNotBlank(deptInfo.getTenantCode())) {
				deptInfo.setParentId(deptInfo.getTenantCode());
			}
			deptService.insertDept(deptInfo);
			return new ApiBaseResponse<Boolean>(RetStatusEnum.SUCCESS,Constants.API_RESPONSE_SUCCESS_CODE,  Constants.API_RESPONSE_SUCCESS_MESSAGE, true);
		} catch (Exception e) {
			logger.error("insert dept info error, cause ", e);
			return new ApiBaseResponse<Boolean>(RetStatusEnum.FAIL,Constants.API_RESPONSE_FAIL_CODE,  Constants.API_RESPONSE_FAIL_MESSAGE, false);
		}
		
	}
	
	/**
	 * 修改组织机构
	 */
	@RequestMapping("/editPre")
	public String edit(ModelMap model, String id) {
		
		DeptInfo info = deptService.selectDeptById(id);
		model.put("dept", info);
		// 如果超级管理员时需要给出可选租户
		if (SSOClientUtils.getInstance().isAdmin()) {
			TenantInfo tenantQuery = new TenantInfo();
			tenantQuery.setStatus(Constants.COMMON_VALID);
			model.put("tenantList", tenantService.findTanantList(tenantQuery , new PageInfo(1000)));
		}
		
		List<String> deptNameList = new ArrayList<String>();
		if(SSOClientUtils.getInstance().isAdmin()) {
			TenantInfo tenantInfo = tenantService.findTenantInfoByCode(info.getTenantCode());
			if(tenantInfo != null) {
				deptNameList.add(tenantInfo.getTenantName());
			}
		}
		
		List<DeptInfo> ancestorList = deptService.findAncestorDept(info.getAncestors() , info.getDeptCode());
		if(ancestorList != null) {
			for(DeptInfo deptInfo : ancestorList) {
				deptNameList.add(deptInfo.getDeptName());
			}
		}
		
		model.put("deptAncestor", StringUtils.join(deptNameList.toArray(new String[0]), " - "));
		
		return "user-app/deptInfo/edit";
	}

	/**
	 * 修改保存组织机构
	 */
	@SecurityChecker("user:deptInfo:edit")
	@RequestMapping("/edit")
	@ResponseBody
	@OperLog(functionName="修改",menuName="组织机构管理")
	public ApiBaseResponse<Boolean> editSave(DeptInfo dept) {
		dept.setUpdateBy(SSOClientUtils.getInstance().findCurrentUser().getLoginName());
		int u = deptService.updateDept(dept);
		if (u != 1) {
			logger.error("update dept info error, expected 1 but {}", u);
			return new ApiBaseResponse<Boolean>(RetStatusEnum.FAIL,Constants.API_RESPONSE_FAIL_CODE,  Constants.API_RESPONSE_FAIL_MESSAGE, false);
		}
		return new ApiBaseResponse<Boolean>(RetStatusEnum.SUCCESS,Constants.API_RESPONSE_SUCCESS_CODE,  Constants.API_RESPONSE_SUCCESS_MESSAGE, true);
	}

	private String deptCloseCheck(String id) {
		if (deptService.countDeptByParentId(id) > 0) {
			return "存在下级组织机构,不允许删除";
		}
		if (deptService.countUsersByDeptId(id) > 0) {
			return "组织机构存在用户,不允许删除";
		}
		return null;
	}
	
	/**
	 * 删除组织机构
	 */
	@SecurityChecker("user:deptInfo:remove")
	@RequestMapping("/remove")
	@ResponseBody
	@OperLog(functionName="删除",menuName="组织机构管理")
	public ApiBaseResponse<Boolean> remove(String id) {
		String rst = deptCloseCheck(id);
		if (StringUtils.isNotBlank(rst)) {
			return new ApiBaseResponse<Boolean>(RetStatusEnum.FAIL,Constants.API_RESPONSE_FAIL_CODE,  rst, false);
		}
		// 实际更新了标识为失效
		boolean del = deptService.deleteDeptById(id) > 0 ? true : false;
		if (!del) {
			return new ApiBaseResponse<Boolean>(RetStatusEnum.FAIL,Constants.API_RESPONSE_FAIL_CODE, Constants.API_RESPONSE_FAIL_MESSAGE, false);
		}
		return new ApiBaseResponse<Boolean>(RetStatusEnum.SUCCESS,Constants.API_RESPONSE_SUCCESS_CODE, Constants.API_RESPONSE_SUCCESS_MESSAGE, true);
	}

	/**
	 * 校验组织机构名称
	 */
	@RequestMapping("/checkDeptNameUnique")
	@ResponseBody
	public ApiBaseResponse<Boolean> checkDeptNameUnique(String parentId , String id , String deptName) {
		return new ApiBaseResponse<Boolean>(RetStatusEnum.SUCCESS,Constants.API_RESPONSE_SUCCESS_CODE, 
				Constants.API_RESPONSE_SUCCESS_MESSAGE, deptService.checkDeptNameUnique(parentId , deptName , id));
	}
	
	/**
	 * 校验组织机构名称
	 */
	@RequestMapping("/checkDeptCodeUnique")
	@ResponseBody
	public ApiBaseResponse<Boolean> checkDeptCodeUnique(String id , String deptCode) {
		return new ApiBaseResponse<Boolean>(RetStatusEnum.SUCCESS,Constants.API_RESPONSE_SUCCESS_CODE, 
				Constants.API_RESPONSE_SUCCESS_MESSAGE, deptService.checkDeptCodeUnique(id , deptCode));
	}

}
